package com.ize.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5util {

    // 定义十六进制字符数组
    private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    // 初始化MessageDigest实例
    private static final MessageDigest MESSAGE_DIGEST;

    static {
        try {
            MESSAGE_DIGEST = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("MD5算法不可用。", e);
        }
    }

    /**
     * 生成字符串的MD5校验值
     *
     * @param s 字符串
     * @return MD5校验值
     */
    public static String getMD5String(String s) {
        return getMD5String(s.getBytes());
    }

    private static String getMD5String(byte[] bytes) {
        // 使用指定的字节更新摘要
        MESSAGE_DIGEST.update(bytes);
        // 获得密文
        byte[] mdBytes = MESSAGE_DIGEST.digest();

        // 把密文转换成十六进制的字符串形式
        return bytesToHex(mdBytes);
    }

    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(byteToHex(b));
        }
        return sb.toString();
    }

    private static String byteToHex(byte b) {
        int n = b & 0xFF; // 取字节的后8位，保证结果为正数
        int d1 = n >>> 4; // 取高4位
        int d2 = n & 0x0F; // 取低4位
        return "" + HEX_DIGITS[d1] + HEX_DIGITS[d2];
    }
}


